#include "StdAfx.h"
#include "Skill.h"
#include "SkillFactory.h"
#include "StyleSkill.h"
#include "InstantSkill.h"
#include "DelayedSkill.h"
#include "PassiveSkill.h"
#include "NormalAttack.h"
#include "SkillInfoParser.h"


SkillFactory::SkillFactory()
{
	m_pStylePool = new CMemoryPoolFactory<StyleSkill>;
	m_pInstantPool = new CMemoryPoolFactory<InstantSkill>;
	m_pDelayedPool = new CMemoryPoolFactory<DelayedSkill>;
	m_pPassivePool = new CMemoryPoolFactory<PassiveSkill>;
	m_pNormalPool = new CMemoryPoolFactory<NormalAttack>;
}

SkillFactory::~SkillFactory()
{
	SAFE_DELETE( m_pStylePool );
	SAFE_DELETE( m_pInstantPool );
	SAFE_DELETE( m_pDelayedPool );
	SAFE_DELETE( m_pPassivePool );
	SAFE_DELETE( m_pNormalPool );
}

VOID SkillFactory::Release()
{
	if( m_pStylePool )		m_pStylePool->Release();
	if( m_pInstantPool )	m_pInstantPool->Release();
	if( m_pDelayedPool )	m_pDelayedPool->Release();
	if( m_pPassivePool )	m_pPassivePool->Release();
	if( m_pNormalPool )		m_pNormalPool->Release();
}

VOID SkillFactory::Init( DWORD dwPlayerSkillPool, DWORD dwNPCSkillPool )
{
	m_pInstantPool->Initialize( dwPlayerSkillPool+dwNPCSkillPool, (dwPlayerSkillPool+dwNPCSkillPool)/4 );
	m_pDelayedPool->Initialize( (dwPlayerSkillPool+dwNPCSkillPool)/2, (dwPlayerSkillPool+dwNPCSkillPool)/8 );

	m_pNormalPool->Initialize( dwPlayerSkillPool, dwPlayerSkillPool/4 );
	m_pStylePool->Initialize( dwPlayerSkillPool/2, dwPlayerSkillPool/4 );
	m_pPassivePool->Initialize( dwPlayerSkillPool*4, dwPlayerSkillPool );
}

Skill * SkillFactory::AllocSkill( eSKILL_TYPE eSkillType, SkillScriptInfo *pBaseSkillInfo )
{
	Skill *pSkill = NULL; 

	if( pBaseSkillInfo )
	{
		if( pBaseSkillInfo->m_bySkillType == SKILL_TYPE_PASSIVE )
		{
			eSkillType = SKILL_TYPE_PASSIVE;
		}
		else if( !pBaseSkillInfo->m_wSkillCasting && !pBaseSkillInfo->m_wFlyingLifeTime )
		{
			eSkillType = SKILL_TYPE_ACTIVE_INSTANT;
		}
		else
		{
			eSkillType = SKILL_TYPE_ACTIVE_DELAYED;
		}
	}
	
	switch( eSkillType )
	{
	case SKILL_TYPE_PASSIVE:
		pSkill = m_pPassivePool->Alloc();
		break;

	case SKILL_TYPE_ACTIVE_INSTANT:
		pSkill = m_pInstantPool->Alloc();
		break;

	case SKILL_TYPE_ACTIVE_DELAYED:
		pSkill = m_pDelayedPool->Alloc();
		break;

	case SKILL_TYPE_STYLE:
		pSkill = m_pStylePool->Alloc();
		break;

	case SKILL_TYPE_NORMAL:
		pSkill = m_pNormalPool->Alloc();
		break;

	default:
		SUNLOG( eCRITICAL_LOG,  "[SkillFactory::AllocSkill] The SkillType doesn't exist" );
	}

	return pSkill;
}


VOID SkillFactory::FreeSkill( Skill* pSkill )
{
	switch( pSkill->GetSkillType() )
	{
	case SKILL_TYPE_PASSIVE:
		m_pPassivePool->Free( (PassiveSkill*)pSkill );
		break;

	case SKILL_TYPE_ACTIVE_INSTANT:
		m_pInstantPool->Free( (InstantSkill*)pSkill );
		break;

	case SKILL_TYPE_ACTIVE_DELAYED:
		m_pDelayedPool->Free( (DelayedSkill*)pSkill );
		break;

	case SKILL_TYPE_STYLE:
		m_pStylePool->Free( (StyleSkill*)pSkill );
		break;

	case SKILL_TYPE_NORMAL:
		m_pNormalPool->Free( (NormalAttack*)pSkill );
		break;

	default:
		SUNLOG( eCRITICAL_LOG,  "[SkillFactory::FreeSkill] The SkillType doesn't exist" );
	}
}


VOID SkillFactory::DisplayPoolInfo()
{
	DISPMSG( "[%4u,%4u][band:%u node:%u] m_pStylePool\n", m_pStylePool->GetPoolBasicSize(), m_pStylePool->GetPoolExtendSize(), 
		m_pStylePool->GetNumberOfBands(), m_pStylePool->GetAvailableNumberOfTypes() );
	DISPMSG( "[%4u,%4u][band:%u node:%u] m_pInstantPool\n", m_pInstantPool->GetPoolBasicSize(), m_pInstantPool->GetPoolExtendSize(), 
		m_pInstantPool->GetNumberOfBands(), m_pInstantPool->GetAvailableNumberOfTypes() );
	DISPMSG( "[%4u,%4u][band:%u node:%u] m_pDelayedPool\n", m_pDelayedPool->GetPoolBasicSize(), m_pDelayedPool->GetPoolExtendSize(), 
		m_pDelayedPool->GetNumberOfBands(), m_pDelayedPool->GetAvailableNumberOfTypes() );
	DISPMSG( "[%4u,%4u][band:%u node:%u] m_pPassivePool\n", m_pPassivePool->GetPoolBasicSize(), m_pPassivePool->GetPoolExtendSize(), 
		m_pPassivePool->GetNumberOfBands(), m_pPassivePool->GetAvailableNumberOfTypes() );
	DISPMSG( "[%4u,%4u][band:%u node:%u] m_pNormalPool\n", m_pNormalPool->GetPoolBasicSize(), m_pNormalPool->GetPoolExtendSize(), 
		m_pNormalPool->GetNumberOfBands(), m_pNormalPool->GetAvailableNumberOfTypes() );
}














